package cn.hg.jbsa.config;

import java.io.IOException;
import java.io.Writer;

import com.jfinal.config.Constants;
import com.jfinal.core.JFinal;
import com.jfinal.ext.handler.ContextPathHandler;
import com.jfinal.kit.JsonKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.IPlugin;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidStatViewHandler;

import cn.hg.jboot.core.directive.InParasDirective;
import cn.hg.jboot.core.directive.LikeParaDirective;
import cn.hg.jboot.core.directive.OrParasDirective;
import cn.hg.jboot.core.directive.ParaDefDirective;
import cn.hutool.core.text.CharSequenceUtil;
import io.jboot.Jboot;
import io.jboot.aop.jfinal.JfinalHandlers;
import io.jboot.aop.jfinal.JfinalPlugins;
import io.jboot.core.listener.JbootAppListenerBase;
import io.jboot.db.SqlDebugger;
import io.jboot.web.handler.JbootActionReporter;

/**
 * @author 胡高
 * @date 2022/01/07
 */
public class JbsaAppListener extends JbootAppListenerBase {
    private static class LogOutWriter extends Writer {
        private Log LOG = Log.getLog(JbootActionReporter.class);

        @Override
        public void close() throws IOException {
        }

        @Override
        public void flush() throws IOException {
        }

        @Override
        public void write(char[] cbuf, int off, int len) throws IOException {
        }

        @Override
        public void write(String str) throws IOException {
            this.LOG.info(str);
        }
    }

    private Log LOG = Log.getLog(JbsaAppListener.class);



    /* (non-Javadoc)
     * @see io.jboot.core.listener.JbootAppListenerBase#onConstantConfig(com.jfinal.config.Constants)
     */
    @Override
    public void onConstantConfig(Constants constants) {
        super.onConstantConfig(constants);

        // 替换RenderFactory
        constants.setRenderFactory(new JbsaRenderFactory());

        // 错误页面设置
        constants.setError401View("/admin/error/401.html");
        constants.setError403View("/admin/error/403.html");
        constants.setError404View("/admin/error/404.html");
        constants.setError500View("/admin/error/500.html");

        // SQL输出设置
        SqlDebugger.setPrinter(SqlDebugger.SqlDebugPrinter.LOG_PRINTER);
    }

    /* (non-Javadoc)
     * @see io.jboot.core.listener.JbootAppListenerBase#onHandlerConfig(io.jboot.aop.jfinal.JfinalHandlers)
     */
    @Override
    public void onHandlerConfig(JfinalHandlers handlers) {
        super.onHandlerConfig(handlers);
        //         handlers.add(new FakeStaticHandler(".html", "/admin/", "/pear/"));
        handlers.add(new ContextPathHandler("ctxPath"));
        handlers.add(0, new DruidStatViewHandler("/admin/system/druid"));
    }

    @Override
    public void onPluginConfig(JfinalPlugins plugins) {
        for (IPlugin  plugin : plugins.getPluginList()) {
            if (plugin instanceof ActiveRecordPlugin) {
                ActiveRecordPlugin arp = (ActiveRecordPlugin) plugin;
                arp.addSqlTemplate("/sql/jbsa.admin.sql"); // 加载system的sql模板
                arp.setDevMode(Jboot.isDevMode());

                /*
                 * 自定义的SQL模板引擎指令
                 */
                arp.getEngine().addDirective(InParasDirective.DIRECTIVE_NAME, InParasDirective.class);
                arp.getEngine().addDirective(OrParasDirective.DIRECTIVE_NAME, OrParasDirective.class);
                arp.getEngine().addDirective(ParaDefDirective.DIRECTIVE_NAME, ParaDefDirective.class);
                arp.getEngine().addDirective(LikeParaDirective.DIRECTIVE_NAME, LikeParaDirective.class);
            }
        }
    }

    /* (non-Javadoc)
     * @see io.jboot.core.listener.JbootAppListenerBase#onStart()
     */
    @Override
    public void onStartBefore() {
        super.onStartBefore();

        // Action日志输出设置
        JbootActionReporter.setWriter(new LogOutWriter());
    }

    /* (non-Javadoc)
     * @see io.jboot.core.listener.JbootAppListenerBase#onStartFinish()
     */
    @Override
    public void onStartFinish() {
        super.onStartFinish();

        // **********************************************************************
        StringBuilder startStr = new StringBuilder("\r\n")
            .append("                       _oo0oo_ \r\n")
            .append("                      o8888888o \r\n")
            .append("                      88\" . \"88 \r\n")
            .append("                      (| - - |) \r\n")
            .append("                      0\\  3  /0 \r\n")
            .append("                    ___/`---'\\___ \r\n")
            .append("                  .' \\\\|     |// '. \r\n")
            .append("                 / \\\\|||  :  |||// \\ \r\n")
            .append("                / -||||| -:- |||||- \\ \r\n")
            .append("               |   | \\\\\\  -  /// |   | \r\n")
            .append("               | \\_|  ''\\---/''  | _/|  \r\n")
            .append("               \\  .-\\__  '_'  __/ -. / \r\n")
            .append("            ____'. .'  /--.--\\    . .' \r\n")
            .append("          .\"\" '< `.____\\_<|>_/____.' >' \"\". \r\n")
            .append("          | | : `- \\`.;`\\ _ /`;.`/ -` : | | \r\n")
            .append("          \\ \\ `-.   \\_ __\\ /__ _/   .-` / / \r\n")
            .append("  =====`-.____`-.___ \\_________/ ___.-`____.-`===== \r\n")
            .append("\r\n")
            .append("后台服务启动成功，望佛祖保佑没有Bug！");
        this.LOG.info(startStr.toString());
        String actionList = CharSequenceUtil.format("Action列表：{}", JsonKit.toJson(JFinal.me().getAllActionKeys()));
        System.out.println(actionList);
    }

}
